package org.orz.cloud.auth;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import org.orz.cloud.auth.domain.UserInfo;
import org.orz.cloud.auth.domain.UserToken;
import org.orz.cloud.common.exception.BusinessException;
import org.orz.cloud.common.utils.ThreadLocalUtils;
import org.orz.cloud.redis.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.orz.cloud.auth.AuthConstants.USER_TOKEN_KEY;

public class UserUtil {

    private static final Logger log = LoggerFactory.getLogger(UserUtil.class);

    /**
     * 获取当前用户信息，如果没有获取到，就抛出异常
     * @return 当前用户信息
     */
    public static UserInfo getUserInfoWithExistCheck(){
        UserInfo userInfo = getUserInfo();
        if(userInfo == null){
            throw new BusinessException(AuthErrorEnum.NOT_LOGIN);
        }
        return userInfo;
    }

    /**
     * 获取当前用户信息，如果没有获取到，就返回null
     * @return 当前用户信息
     */
    public static UserInfo getUserInfo() {
        //从threadLocal中获取token
        String token = ThreadLocalUtils.getValue(USER_TOKEN_KEY, String.class);
        log.debug("current request's token is : {}", token);
        if(StrUtil.isBlank(token)){
            return null;
        }
        return getUserInfoByToken(token);
    }

    /**
     * 根据token获取用户信息
     */
    public static UserInfo getUserInfoByToken(String token){
        //到redis中查询userToken信息
        String tokenStr = RedisUtil.get(AuthConstants.REDIS_KEY_USER_TOKEN + token);
        log.debug("get userToken from redis : {}", tokenStr);
        if(StrUtil.isBlank(tokenStr)){
            log.warn("get userToken from redis, but we don't found userToken or userToken is null.");
            return null;
        }

        UserToken userToken = JSON.parseObject(tokenStr, UserToken.class);
        if(userToken.getAccountId() == null){
            log.warn("found userToken, but accountId is null");
            return null;
        }

        //根据userToken获取userInfo信息
        String userInfoStr = RedisUtil.get(AuthConstants.REDIS_KEY_USER_INFO + userToken.getAccountId());
        if(StrUtil.isBlank(userInfoStr)){
            log.warn("found userToken, but we don't found userInfo in redis, or userInfo is null");
            return null;
        }
        return JSON.parseObject(userInfoStr, UserInfo.class);
    }
}
